﻿using System;
using System.Collections.Generic;
using System.Collections.Specialized;
using System.Text.RegularExpressions;

namespace StyleAnalyzer
{
	/// <summary>
	/// Represents a rule in the the CSS language.
	/// </summary>
	public class CssRule
	{
		private static readonly Regex SelectorDivider = new Regex(@"^([^{]*)", RegexOptions.Compiled | RegexOptions.IgnoreCase);
		private static readonly Regex PropertyDivider = new Regex("{([^}].*?)}", RegexOptions.Compiled);

		/// <summary>
		/// Initializes a new instance of the <see cref="CssRule"/> class.
		/// </summary>
		/// <param name="rule">The rule.</param>
		public CssRule(string rule)
		{
			this.Properties = new Dictionary<string, string>();
			this.InvalidProperties = new StringCollection();

			Parse(rule);
		}

		/// <summary>
		/// Gets the CSS selector of this rule.
		/// </summary>
		/// <value>The selector.</value>
		public string Selector
		{
			get;
			private set;
		}

		/// <summary>
		/// Gets the CSS properties that applies to this rule.
		/// </summary>
		/// <value>The properties.</value>
		public Dictionary<string, string> Properties
		{
			get;
			private set;
		}

		/// <summary>
		/// Gets the invalid properties - properties with a bad syntax that couldn't be parsed.
		/// </summary>
		/// <value>The invalid properties.</value>
		public StringCollection InvalidProperties
		{
			get;
			private set;
		}

		/// <summary>
		/// Gets a value indicating whether this instance is succesfully parsed.
		/// </summary>
		/// <value>
		/// 	<c>true</c> if this instance is succesfully parsed; otherwise, <c>false</c>.
		/// </value>
		public bool IsSuccessfullyParsed
		{
			get
			{
				return InvalidProperties.Count == 0;
			}
		}

		private void Parse(string rule)
		{
			Match selectorMatch = SelectorDivider.Match(rule);
			Match propertyMatch = PropertyDivider.Match(rule);

			if (selectorMatch.Success && propertyMatch.Success)
			{
				this.Selector = selectorMatch.Value;
				ParseProperties(propertyMatch);
			}
		}

		private void ParseProperties(Match propertyMatch)
		{
			string[] line = propertyMatch.Groups[1].Value.Split(new string[] { ";" }, StringSplitOptions.RemoveEmptyEntries);
			foreach (string item in line)
			{
				string[] args = item.Split(':');
				if (args.Length == 2)
				{
					this.Properties.Add(args[0], args[1]);
				}
				else
				{
					InvalidProperties.Add(item);
				}
			}
		}

		/// <summary>
		/// Returns a <see cref="System.String"/> that represents this instance.
		/// </summary>
		/// <returns>
		/// A <see cref="System.String"/> that represents this instance.
		/// </returns>
		public override string ToString()
		{
			return Selector ?? base.ToString();
		}
	}
}
